#include <QDebug>
#include <QMap>
#include <QDir>
#include "Node.h"
#include "Project.h"

static QMap<QString, Node*> __allNodes;

void removeNode(const QString & path)
{
    if (__allNodes.contains(path))
        __allNodes.remove(path);
}

Node * findNode(const QString & path)
{
    if (__allNodes.contains(path))
        return __allNodes[path];
    return NULL;
}

Node::Node(): QObject()
{

}

Node::Node(const Node &node):QObject()
{
    _info = node._info;
    _path = node._path;
    _spec = node._spec;
    _type = node._type;
    _modified = node._modified;
    _parent = node._parent;
    _children = node._children;
}

Node::Node(const QFileInfo & finfo, const QString & spec, NodeTypes type): QObject()
{
    _spec = spec;
    _info = finfo;
    _path = finfo.absoluteFilePath();
    _type = type;
    _modified = false;
}

Node::Node(const QString & path, const QString & spec, NodeTypes type): QObject()
{
    _spec = spec;
    _info = QFileInfo(path);
    _path = path;
    _type = type;
    _modified = false;
}

Node::~Node()
{
    if (_parent)
        _parent->_children.removeOne(this);
    _parent = NULL;
    removeNode(path());
    qDeleteAll(_children);
    _children.clear();
    //qDebug() << "deleted" << _path;
}

void Node::init()
{
    _parent = findNode(_info.dir().absolutePath());
    if (_parent){
        _parent->_children.insert(_parent->calcPosition(this), this);
    }
    __allNodes.insert(_info.absoluteFilePath(), this);
}

int Node::calcPosition(Node *node)
{
    NodeTypes type = node->nodeType();
    if (type == DirectoryType || type == PyModuleType){
        for(int i = 0; i < _children.length(); ++i){
            if (_children[i]->nodeType() != DirectoryType && _children[i]->nodeType() != PyModuleType)
                return i;
            if (_children[i]->name().toLower().compare(node->name().toLower()) > 0)
                return i;
        }
        return _children.length();
    }
    if (type == DesignerType || type == ResourcesType){
        for(int i = 0; i < _children.length(); ++i){
            if (_children[i]->nodeType() == DirectoryType || _children[i]->nodeType() == PyModuleType)
                continue;
            if (_children[i]->nodeType() == FileType)
                return i;
            if (_children[i]->name().toLower().compare(node->name().toLower()) > 0)
                return i;
        }
        return _children.length();
    }
    if (type == FileType){
        for(int i = 0; i < _children.length(); ++i){
            if (_children[i]->nodeType() == DirectoryType || _children[i]->nodeType() == DesignerType || _children[i]->nodeType() == ResourcesType || _children[i]->nodeType() == PyModuleType)
                continue;
            if (_children[i]->name().toLower().compare(node->name().toLower()) > 0)
                return i;
        }
        return _children.length();
    }
    return _children.length();
}

void Node::addNode(Node* node)
{
    _children.insert(calcPosition(node), node);
}

int Node::row()
{
    if (q_check_ptr(_parent))
        return _parent->_children.indexOf(this);
    return 0;
}

QString Node::path()
{
    return _info.absoluteFilePath();
}

QString Node::parentPath()
{
    return _parent->path();
}

QString Node::name()
{
    return _info.fileName();
}

QString Node::dirName()
{
    return _info.absolutePath();
}

QString Node::baseName()
{
    return _info.baseName();
}

QFileInfo Node::fileInfo()
{
    return _info;
}

bool Node::isModified()
{
    return _modified;
}

void Node::setModified(bool modified)
{
    _modified = modified;
}

QString Node::spec()
{
    return _spec;
}


void Node::reparent(Node * newParent)
{
    _parent->_children.removeOne(this);
    _parent = newParent;
    _parent->addNode(this);
}

void Node::checkExistingChildren(const QStringList & extFilter)
{
    bool deleted = false;
    QList<Node*> toDelete;
    do{
        deleted = false;
        for(int c = 0; c < _children.length(); ++c){
            if (!_children[c]->_spec.isEmpty()){
                _children[c]->checkExistingChildren(extFilter);
                if (_children[c]->_children.length() == 0 && !toDelete.contains(_children[c])){
                    toDelete.append(_children[c]);
                    deleted = true;
                    break;
                }
            } else if (!QFile::exists(_children[c]->path()) && !toDelete.contains(_children[c])){
                toDelete.append(_children[c]);
                deleted = true;
                break;
            } else if (_children[c]->extension() != "" && !extFilter.contains("*."+_children[c]->extension()) && !toDelete.contains(_children[c])){
                toDelete.append(_children[c]);
                deleted = true;
                break;
            }
            _children[c]->checkExistingChildren(extFilter);
        }
    } while(deleted);
    if (toDelete.length() > 0){
        emit nodeToDestroy(toDelete);
    }
}

NodeTypes Node::nodeType()
{
    return _type;
}

void Node::changeType(NodeTypes newType)
{
    _type = newType;
}

QString Node::extension()
{
    if (_type == FileType)
        return name().split(".").last();
    return "";
}

//Q_DECLARE_METATYPE(Node*);
